home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / gcore / ds3100.md / process.c < prev   
Encoding:
C/C++ Source or Header  |  1992-06-25  |  9.3 KB  |  357 lines

  1. /* 
  2.  * process.c --
  3.  *
  4.  *    Routines for finding and manipulating processes for the
  5.  *    gcore program.
  6.  *
  7.  * Copyright 1988 Regents of the University of California
  8.  * Permission to use, copy, modify, and distribute this
  9.  * software and its documentation for any purpose and without
  10.  * fee is hereby granted, provided that the above copyright
  11.  * notice appear in all copies.  The University of California
  12.  * makes no representations about the suitability of this
  13.  * software for any purpose.  It is provided "as is" without
  14.  * express or implied warranty.
  15.  */
  16.  
  17. #ifndef lint
  18. static char rcsid[] = "$Header: /sprite/src/cmds/gcore/RCS/process.c,v 1.4 91/10/25 10:28:36 jhh Exp $ SPRITE (Berkeley)";
  19. #endif not lint
  20.  
  21.  
  22. #include <ctype.h>
  23. #include <option.h>
  24. #include <status.h>
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <signal.h>
  29. #include <sys/types.h>
  30. #include <sys/file.h>
  31. #include <proc.h>
  32. #include <vm.h>
  33.  
  34. #include "gcore.h"
  35.  
  36.  
  37. /*
  38.  *----------------------------------------------------------------------
  39.  *
  40.  *  FindProcess --
  41.  *
  42.  *      Find the process and argument string of the specified process.
  43.  *
  44.  * Results:
  45.  *    The process state.
  46.  *
  47.  *
  48.  * Side effects:
  49.  *      The none.
  50.  *
  51.  *----------------------------------------------------------------------
  52.  */
  53.  
  54. int
  55. FindProcess(pid,argString,segSizePtr,sigStatePtr)
  56.     int        pid;        /* Process ID to locate. */
  57.     char    *argString;    /* Area to place argument string of
  58.                  * the specified process. */
  59.     int        *segSizePtr;    /* Array to store segment size in. */
  60.     int        *sigStatePtr;   /* Out: State of the signal masks. 
  61.                  * In: The signal to check. */
  62. {
  63.     int  pcbsUsed;
  64.     ReturnStatus status;
  65.     Proc_PCBInfo    pcb;
  66.     Proc_PCBInfo    *pcbPtr;
  67.     Proc_PCBArgString    pcbArgString;
  68.     int            procState;
  69.  
  70.     /*
  71.      * Find the PCB of the specifed process.
  72.      */
  73.     procState = NOT_FOUND_STATE;
  74.     pcbPtr = &pcb;
  75.     status = Proc_GetPCBInfo(Proc_PIDToIndex(pid),
  76.                  Proc_PIDToIndex(pid), PROC_MY_HOSTID,
  77.                  sizeof(Proc_PCBInfo),
  78.                  pcbPtr, &pcbArgString, &pcbsUsed);
  79.     if (status != SUCCESS) {
  80.     if (debug) {
  81.         (void) fprintf(stderr, "Proc_GetPCBInfo for pid 0x%x error: %s",pid,
  82.             Stat_GetMsg(status));
  83.     }
  84.     return procState;
  85.     }
  86.  
  87.     /*
  88.      * The process we got info for may not be the one that was
  89.      * requested (different generation numbers);  check to be sure.
  90.      */
  91.     if (pid != pcbPtr->processID) {
  92.     if (debug) {
  93.         (void) fprintf(stderr,
  94.             "Proc_GetPCBInfo: looking for 0x%x but found 0x%x\n",
  95.            pid,pcbPtr->processID);    
  96.         }
  97.         return procState;
  98.     }
  99.     /*
  100.      * Check the process state.
  101.      */
  102.     switch (pcbPtr->state) {
  103.     case PROC_SUSPENDED: {
  104.     procState = (pcbPtr->genFlags & (PROC_DEBUGGED | PROC_ON_DEBUG_LIST)) ?
  105.                 DEBUG_STATE : 
  106.                 SUSPEND_STATE;
  107.     break;
  108.         }
  109.     case PROC_RUNNING:
  110.     case PROC_READY:
  111.     case PROC_WAITING: {
  112.     procState = RUN_STATE;
  113.     break;
  114.         }
  115.     default:
  116.     procState = UNKNOWN_STATE;
  117.     }
  118.  
  119.     /*
  120.      * Copy the argument string to return it.
  121.      */
  122.     if (argString != NULL) {
  123.     char    *ap = pcbArgString.argString;
  124.     (void) strncpy(argString,ap,MAX_ARG_STRING_SIZE-1);
  125.     argString[MAX_ARG_STRING_SIZE-1] = 0;
  126.     if (debug) {
  127.         (void) fprintf(stderr,"FindProcess: Argument string \"%s\"\n",ap);
  128.     }
  129.    }
  130.    /*
  131.     * Lookup the segment size from the virtual memory system.
  132.     */
  133.     if (segSizePtr != (int *) 0) {
  134.       Vm_SegmentInfo     segBuf[VM_NUM_SEGMENTS];
  135.       int                 pagesize = getpagesize();
  136.  
  137.       status = Vm_GetSegInfo(pcbPtr, 0, sizeof(Vm_SegmentInfo),
  138.                      &(segBuf[1]));
  139.       if (status != SUCCESS) {
  140.         if(debug) {
  141.         (void) fprintf(stderr, 
  142.             "Couldn't read segment info for pid %x: %s\n",
  143.             pcbPtr->processID, Stat_GetMsg(status));
  144.         }
  145.       }
  146.       segSizePtr[TEXT_SEG] = segBuf[VM_CODE].numPages*pagesize;
  147.       segSizePtr[DATA_SEG] = segBuf[VM_HEAP].numPages*pagesize;
  148.       segSizePtr[STACK_SEG] = segBuf[VM_STACK].numPages*pagesize;
  149.     }
  150.  
  151.    if (sigStatePtr != (int *) 0) {
  152.     int    spriteSig;
  153.     (void) Compat_UnixSignalToSprite(*sigStatePtr,&spriteSig);
  154.     if (pcbPtr->sigActions[spriteSig] == SIG_IGNORE_ACTION) {
  155.         *sigStatePtr = SIG_IGNORING;
  156.     } else if (pcbPtr->sigActions[spriteSig] > SIG_NUM_ACTIONS) {
  157.         *sigStatePtr = SIG_HANDLING;
  158.     } else if (pcbPtr->sigHoldMask & spriteSig) {
  159.         *sigStatePtr = SIG_HOLDING;
  160.     } else {
  161.         *sigStatePtr = 0;
  162.     }
  163.  
  164.    }
  165.    return (procState);
  166.  
  167. }
  168.  
  169. /*
  170.  *----------------------------------------------------------------------
  171.  *
  172.  *  XferSegmentFromProcess --
  173.  *
  174.  *      Transfer a memory segment from a process into a file. 
  175.  *
  176.  *     This routines transfers the memory image from the process 
  177.  *    specified by pid into the file coreFile. The transfer starts
  178.  *    at the address specified by startAddress and ends on the first
  179.  *    unreadable page. 
  180.  *
  181.  * Results:
  182.  *    Number of bytes written to file. -1 if an error occured.
  183.  *
  184.  * Side effects:
  185.  *      The file is written.
  186.  *
  187.  *----------------------------------------------------------------------
  188.  */
  189.  
  190. int
  191. XferSegmentFromProcess(pid,startAddress,coreFile)
  192.     int          pid;        /* Process ID to operate on. */
  193.     unsigned int startAddress;    /* Address to start with. */
  194.     FILE    *coreFile;    /* File to write image to. */
  195. {
  196.     ReturnStatus                status = SUCCESS;
  197.     int                xferSize = getpagesize();
  198.     char            *xferBuffer;
  199.     unsigned int        nextAddress;
  200.  
  201.     /*
  202.      * Round the starting address to point at the start of its page.
  203.      */
  204.  
  205.     startAddress = startAddress & ~(xferSize-1);
  206.     nextAddress = startAddress;
  207.     /*
  208.      * Allocate the buffer to copy.
  209.      */
  210.     xferBuffer = malloc(xferSize);
  211.     /*
  212.      * Read from memory and write to file until we get an error.
  213.      */
  214.     status = Proc_Debug((Proc_PID)pid,PROC_READ, xferSize, 
  215.                 (char *)nextAddress,xferBuffer);
  216.     while (status == SUCCESS) {
  217.     if (fwrite(xferBuffer,xferSize,1,coreFile) != 1) {
  218.         perror(PROGRAM_NAME);
  219.         return (-1);
  220.     }
  221.     nextAddress += xferSize;
  222.     status = Proc_Debug((Proc_PID) pid,PROC_READ,xferSize,
  223.                 (char *)nextAddress,xferBuffer);
  224.     }
  225.  
  226.     if (debug) {
  227.     (void) fprintf(stderr,"XferSegment 0x%x - 0x%x from 0x%x\n",
  228.             startAddress,nextAddress, pid);
  229.     }
  230.  
  231.     /*
  232.      * Return the number of bytes transfered.
  233.      */
  234.     return (nextAddress-startAddress);
  235. }
  236.  
  237.  
  238. /*
  239.  *----------------------------------------------------------------------
  240.  *
  241.  *  ReadStopInfoFromProcess --
  242.  *
  243.  *      Read the stop info (ie registers and fault code) from
  244.  *    the specified process.
  245.  *
  246.  * Results:
  247.  *    True if operation succeeded false otherwise.
  248.  *
  249.  * Side effects:
  250.  *      The process is "attached" using the Proc_Debug call.
  251.  *
  252.  *----------------------------------------------------------------------
  253.  */
  254.  
  255.  
  256. Boolean
  257. ReadStopInfoFromProcess(pid,signalNumPtr,pcbPtr)
  258.     int        pid;        /* Process ID to read. */
  259.     int        *signalNumPtr;    /* Signal number of fault. */
  260.     struct pcb  *pcbPtr;       /* pcb of process.     */
  261. {
  262.     ReturnStatus    status;
  263.     Proc_DebugState process_state;
  264.  
  265.     /*
  266.      * Attach the process.
  267.      */
  268.     status = Proc_Debug((Proc_PID)pid,PROC_GET_THIS_DEBUG,0,(char *)0,
  269.                         (char *)0);
  270.     if (status != SUCCESS) {
  271.     (void) fprintf(stderr, "%s: Can't attach process 0x%x error: %s", 
  272.             PROGRAM_NAME, pid, Stat_GetMsg(status));
  273.  
  274.     return FALSE;
  275.     }
  276.     /*
  277.      * Read the process's stop state.
  278.      */
  279.     status = Proc_Debug((Proc_PID)pid, PROC_GET_DBG_STATE, 0,
  280.                     (char *)0,(char *)&process_state);
  281.     if (status != SUCCESS) {
  282.     (void) fprintf(stderr, "%s: Read state of process 0x%x error: %s", 
  283.             PROGRAM_NAME, pid, Stat_GetMsg(status));
  284.  
  285.     return FALSE;
  286.     }
  287.     /*
  288.      * Map the Sprite signal to a Unix style signal using a routine 
  289.      * in libc.a.
  290.      */
  291.     (void)Compat_SpriteSignalToUnix(process_state.termStatus,signalNumPtr);
  292.     /*
  293.      * Convert the Mach_RegState structure return by Proc_Debug into a
  294.      * Unix "struct pcb".
  295.      */
  296.     ConvertSpriteRegsToUnixPcb(&process_state.regState,pcbPtr);
  297.     return (TRUE);
  298. }
  299.  
  300. Boolean
  301. AttachProcess(pid)
  302. {
  303.     ReturnStatus    status;
  304.     /*
  305.      * Attach the process.
  306.      */
  307.     status = Proc_Debug((Proc_PID)pid,PROC_GET_THIS_DEBUG,0,(char *)0,
  308.                         (char *)0);
  309.     if (status != SUCCESS) {
  310.     (void) fprintf(stderr, 
  311.             "%s: Error attaching process %x: %s\n", PROGRAM_NAME,
  312.             pid, Stat_GetMsg(status));
  313.  
  314.     return FALSE;
  315.     }
  316.     return TRUE;
  317. }
  318.  
  319. Boolean
  320. DetachProcess(pid)
  321. {
  322.     ReturnStatus    status;
  323.     /*
  324.      * Attach the process.
  325.      */
  326.     status = Proc_Debug((Proc_PID)pid,PROC_DETACH_DEBUGGER,0,(char *)0,
  327.                                  (char *)0);
  328.     if (status != SUCCESS) {
  329.     if (status != PROC_INVALID_PID) { 
  330.         (void) fprintf(stderr, 
  331.             "%s: Error detaching process %x: %s\n", PROGRAM_NAME,
  332.             pid, Stat_GetMsg(status));
  333.     }
  334.     return FALSE;
  335.     }
  336.     return TRUE;
  337. }
  338.  
  339. ConvertSpriteRegsToUnixPcb(spriteRegsPtr,pcbPtr)
  340. Mach_RegState    *spriteRegsPtr;
  341. struct pcb    *pcbPtr;
  342. {
  343.   /* Mach_RegState defined in kernel/machTypes.h */
  344.   /* Copy regs and fp regs into the pcb, then fill in anything else */
  345.   /* that we can. */
  346.   bcopy ((char *)spriteRegsPtr->regs, (char *)pcbPtr->pcb_regs,
  347.      32*sizeof(unsigned int));
  348.   bcopy ((char *)spriteRegsPtr->fpRegs, (char *)pcbPtr->pcb_fpregs,
  349.      32*sizeof(unsigned int));
  350.   pcbPtr->pcb_pc = (int)spriteRegsPtr->pc;
  351.   /* Not very smart right now, but the lo and hi regs will be put in */
  352.   /* these two fields in the pcb, so they can be looked at later. */
  353.   pcbPtr->pcb_resched = (int)spriteRegsPtr->mflo;
  354.   pcbPtr->pcb_sstep = (int)spriteRegsPtr->mfhi;
  355.   pcbPtr->pcb_fpc_csr = (int)spriteRegsPtr->fpStatusReg;
  356. }
  357.